package data

import (
	"azfirewall-gateway/lru"
	"azfirewall-gateway/models"
	"azfirewall-gateway/utils"
	"encoding/json"
	"github.com/syndtr/goleveldb/leveldb"
	"github.com/syndtr/goleveldb/leveldb/opt"
	"os"
)

type APPDATABASE struct {
	SiteDb    *leveldb.DB
	LogsDb    *leveldb.DB
	CertDB    *leveldb.DB
	SiteCache *lru.Cache
	IPListDB  *leveldb.DB
}

func (Self *APPDATABASE) GetSite(key []byte, ro *opt.ReadOptions) (value []byte, err error) {
	v, ok := Self.SiteCache.Get(key)
	if !ok {
		value, err = Self.SiteDb.Get(key, ro)
		if err != nil {
			return
		}
		Self.SiteCache.Add(key, value)
		// 添加到cache中
		return
	}
	value = v.([]byte)
	return
}

func (Self *APPDATABASE) PutSite(key, value []byte, wo *opt.WriteOptions) (err error) {
	err = Self.SiteDb.Put(key, value, wo)
	if err != nil {
		return
	}
	Self.SiteCache.Add(key, value)
	return
}

func (Self *APPDATABASE) DeleteSite(key []byte, wo *opt.WriteOptions) (err error) {
	Self.SiteCache.Remove(key)
	err = Self.SiteDb.Delete(key, wo)
	if err != nil {
		return
	}
	return
}

var (
	Version = "0.0.1"
	DBP     *APPDATABASE
	CFG     *models.Config
)

func InitData() {
	utils.MainLog.Info("数据初始化及载入中...")
	DBP = new(APPDATABASE)
	var err error
	CFG, err = NewConfig("./config.json")
	utils.CheckError("初始化数据工程中遇到错误：", err)
	if err != nil {
		os.Exit(1)
	}
	DBP.SiteDb, err = leveldb.OpenFile("./database/sites", nil)
	utils.CheckError("开启数据库连接时遇到错误：", err)
	if err != nil {
		os.Exit(1)
	}
	DBP.CertDB, err = leveldb.OpenFile("./database/certs", nil)
	utils.CheckError("开启数据库连接时遇到错误：", err)
	if err != nil {
		os.Exit(1)
	}
	DBP.LogsDb, err = leveldb.OpenFile("./database/logs", nil)
	utils.CheckError("开启数据库连接时遇到错误：", err)
	if err != nil {
		os.Exit(1)
	}
	DBP.IPListDB, err = leveldb.OpenFile("./database/ips", nil)
	utils.CheckError("开启数据库连接时遇到错误：", err)
	if err != nil {
		os.Exit(1)
	}
	DBP.SiteCache = lru.New(102400) // 这里根据对象大小以及内存大小酌情考虑cahce对象数量
	utils.MainLog.Info("数据初始化及载入完毕！")
}

func SiteStructToJsonByteArr(s models.Site) []byte {
	data, err := json.Marshal(s)
	if err != nil {
		utils.MainLog.Error("站点信息结构体转Json字符时出现错误：", err)
	}
	return data
}

func JsonByteArrToSiteStruct(d []byte) *models.Site {
	var obj models.Site
	err := json.Unmarshal(d, &obj)
	if err != nil {
		utils.MainLog.Error("站点信息Json字符转结构体时出现错误：", err)
	}
	return &obj
}
